#include <nice2d/background.h>
#include <nice2d/application.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/basicbutton.h>

IMPLEMENT_OBJECT(BasicButtonStyle, ControlStyle)

BasicButtonStyle::BasicButtonStyle()
{
    normalBackground = Background::create(sf::Color(128, 153, 138, 180));
    hoverBackground = Background::create(sf::Color(168, 133, 138, 180));
    pressedBackground = Background::create(sf::Color(188, 113, 118, 180));
    disableBackground = Background::create(sf::Color(102, 102, 102, 140));
}

BasicButtonStyle::~BasicButtonStyle()
{
}

IMPLEMENT_OBJECT(BasicButton, Control)

class BasicButtonData
{
public:
    BasicButtonState buttonState = BasicButtonState::BasicButtonState_Normal;
    BasicButton *button;

    BasicButtonData(BasicButton *thisButton):
        button(thisButton)
    {
        auto desktop = GET_COMPONENT(Application::getInstance(), Desktop);
        auto style = std::dynamic_pointer_cast<BasicButtonStyle>(desktop->getControlStyle("BasicButton"));
        button->setControlStyle(style);
        button->setBackground(style->normalBackground);
    }
};

BasicButton::BasicButton(const sf::Vector2f &size):
    Control(size),
    data(new BasicButtonData(this))
{
}

BasicButton::~BasicButton()
{
}

BasicButtonState BasicButton::getButtonState()const
{
    return data->buttonState;
}

void BasicButton::onMouseEnter()
{
    if (isActive()) {
        data->buttonState = BasicButtonState_Hover;
        onButtonStateChanged();

        onStyleChanged();
    }

    Control::onMouseEnter();
}

void BasicButton::onMouseExit()
{
    if (isActive()) {
        data->buttonState = BasicButtonState_Normal;
        auto style = getControlStyle();
        setBackground(style->normalBackground);
    }

    Control::onMouseExit();
}

void BasicButton::onMousePressed(sf::Mouse::Button button)
{
    if (isActive() && button == sf::Mouse::Button::Left) {
        data->buttonState = BasicButtonState_Down;
        onButtonStateChanged();
        pressed(std::dynamic_pointer_cast<BasicButton>(shared_from_this()));

        auto style = getControlStyle();
        setBackground(style->pressedBackground);
    }
}

void BasicButton::onMouseReleased(sf::Mouse::Button button)
{
    if (isActive() && button == sf::Mouse::Button::Left) {
        data->buttonState = BasicButtonState_Normal;
        onButtonStateChanged();
        released(std::dynamic_pointer_cast<BasicButton>(shared_from_this()));

        auto style = getControlStyle();
        setBackground(style->hoverBackground);
    }
}

void BasicButton::onButtonStateChanged()
{
}

void BasicButton::onStyleChanged()
{
    auto style = getControlStyle();

    if (isActive()) {
        if (data->buttonState == BasicButtonState_Down)
            setBackground(style->pressedBackground);
        else if (data->buttonState == BasicButtonState_Hover)
            setBackground(style->hoverBackground);
        else
            setBackground(style->normalBackground);
    } else
        setBackground(style->disableBackground);
}
